package com.testdemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Xfermode;
import android.util.AttributeSet;
import android.widget.ImageView;

/**
 * Auth：yujunyao
 * Since: 2016/5/19 17:26
 * Email：yujunyao@yonglibao.com
 */
public class GuideImageView extends ImageView {
    /**
     * 从上面我们可以看到PorterDuff.Mode为枚举类,一共有16个枚举值:
     1.PorterDuff.Mode.CLEAR
     所绘制不会提交到画布上。
     2.PorterDuff.Mode.SRC
     显示上层绘制图片
     3.PorterDuff.Mode.DST
     显示下层绘制图片
     4.PorterDuff.Mode.SRC_OVER
     正常绘制显示，上下层绘制叠盖。
     5.PorterDuff.Mode.DST_OVER
     上下层都显示。下层居上显示。
     6.PorterDuff.Mode.SRC_IN
     取两层绘制交集。显示上层。
     7.PorterDuff.Mode.DST_IN
     取两层绘制交集。显示下层。
     8.PorterDuff.Mode.SRC_OUT
     取上层绘制非交集部分。
     9.PorterDuff.Mode.DST_OUT
     取下层绘制非交集部分。
     10.PorterDuff.Mode.SRC_ATOP
     取下层非交集部分与上层交集部分
     11.PorterDuff.Mode.DST_ATOP
     取上层非交集部分与下层交集部分
     12.PorterDuff.Mode.XOR
     异或：去除两图层交集部分
     13.PorterDuff.Mode.DARKEN
     取两图层全部区域，交集部分颜色加深
     14.PorterDuff.Mode.LIGHTEN
     取两图层全部，点亮交集部分颜色
     15.PorterDuff.Mode.MULTIPLY
     取两图层交集部分叠加后颜色
     16.PorterDuff.Mode.SCREEN
     取两图层全部区域，交集部分变为透明色
     */
    private static final Xfermode sXfermode = new PorterDuffXfermode(PorterDuff.Mode.XOR);
    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private Bitmap mFirstLayerBitmap;
    private Bitmap mSecondLayerBitmap;
    private int circleX;
    private int circleY;
    private int radiusX;
    private int radiusY;

    public GuideImageView(Context context) {
        super(context);
    }

    public GuideImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public GuideImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private void recycleBitmap(Bitmap bitmap) {
        if(bitmap != null) {
            bitmap.recycle();
        }
    }

    @Override
    public void invalidate() {
        super.invalidate();
        recycleBitmap(mFirstLayerBitmap);
        recycleBitmap(mSecondLayerBitmap);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        recycleBitmap(mFirstLayerBitmap);
        recycleBitmap(mSecondLayerBitmap);
    }

    public void setData(int circleX, int circleY, int radiusX, int radiusY) {
        this.circleX = circleX;
        this.circleY = circleY;
        this.radiusX = radiusX;
        this.radiusY = radiusY;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (!isInEditMode()) {
            int iLayer = canvas.saveLayer(0.0f, 0.0f, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);

            if(mFirstLayerBitmap == null || mFirstLayerBitmap.isRecycled()) {
                mFirstLayerBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
                Canvas firstLayerCanvas = new Canvas(mFirstLayerBitmap);
                firstLayerCanvas.drawRGB(255, 0, 0);
                if(mSecondLayerBitmap == null || mSecondLayerBitmap.isRecycled()) {
                    mSecondLayerBitmap = createLayer();
                }

                mPaint.reset();
                mPaint.setFilterBitmap(false);
                mPaint.setXfermode(sXfermode);
                firstLayerCanvas.drawBitmap(mSecondLayerBitmap, 0.0f, 0.0f, mPaint);
            }

            if (mFirstLayerBitmap != null) {
                mPaint.setXfermode(null);
                canvas.drawBitmap(mFirstLayerBitmap, 0.0f, 0.0f, mPaint);
                return ;
            }
            canvas.restoreToCount(iLayer);
        }else {
            super.onDraw(canvas);
        }

    }

    private Bitmap createLayer() {
        Bitmap.Config config = Bitmap.Config.ARGB_8888;
        Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), config);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setAntiAlias(true);
        paint.setColor(Color.WHITE);

        RectF mRectF = new RectF(circleX, circleY, radiusX, radiusY);
        canvas.drawOval(mRectF, paint);//此处画椭圆形

        return bitmap;
    }
}
